import axios from 'axios'
import { Cookies } from 'quasar'

export function getResponse (res) {
  return {
    data: res.data.data || res.data,
    status: res.status
  }
}

export function handleError (e) {
  console.error(e)
  if (e.response.status === 401) {
    setTimeout(() => this.$store.commit('quit'), 0)
  }
  return getResponse(e.response)
}

export function getHeaders () {
  const headers = {}
  const token = Cookies.get('csrftoken')

  if (token) {
    headers['X-CSRFToken'] = token
  }

  return headers
}

/**
 *
 * @param {string} api
 * @param {number} id
 * @param {boolean} loading
 * @param {string} instance
 * @returns {Promise<void>}
 */
export async function getRequest ({ api, id, type, loading = true, instance = 'instance', params = {} }) {
  const headers = getHeaders()

  if (id) {
    api = api.replace('{id}', id)
  }

  if (type) {
    api = api.replace('{type}', type)
  }

  if (this.loading !== undefined && loading) {
    this.loading = true
  }

  try {
    const res = await axios.get(api, { headers, params })

    this[instance] = res.data.data || res.data

    return getResponse(res)
  } catch (e) {
    console.log(e)
    return handleError(e)
  } finally {
    if (this.loading !== undefined && loading) {
      this.loading = false
    }
  }
}

/**
 *
 * @param {url} api
 * @param {number} id
 * @param {object} params
 * @param {string} querySet
 * @param {string} count
 * @param {string} mode - set|add|none
 * @param {boolean} loading
 * @param {function} callback
 * @returns {Promise<void>}
 */
export async function getQuerySet ({ api, id, type, page = 1, limit = 10, params = {}, querySet = 'querySet', count = 'count', mode = 'set', callback, loading = true }) {
  const headers = getHeaders()

  if (id) {
    api = api.replace('{id}', id)
  }

  if (type) {
    api = api.replace('{type}', type)
  }

  if (page) {
    params.offset = (page - 1) * limit
  }

  if (limit) {
    params.limit = limit
  }

  if (this.loading !== undefined && loading) {
    this.loading = true
  }

  try {
    const res = await axios.get(api,
      { params, headers }
    )
    const data = res.data

    if (mode === 'set' || !this[querySet]) {
      this[querySet] = data.results
      this[count] = data.count
    } else if (mode === 'add') {
      this[querySet] = this[querySet].concat(data.results)
      this[count] = data.count
    }

    if (this.nextPageQuery !== undefined) {
      this.nextPageQuery = data.next
    }

    if (callback) {
      callback(data)
    }

    return getResponse(res)
  } catch (e) {
    return handleError(e)
  } finally {
    if (this.loading !== undefined && loading) {
      this.loading = false
    }
  }
}

/**
 *
 * @param {string} api
 * @param {number} id
 * @param {object} data
 * @returns {Promise<void>}
 */
export async function postRequest ({ api, id, type, data, loading = true, method = 'post' }) {
  if (id) {
    api = api.replace('{id}', id)
  }

  if (type) {
    api = api.replace('{type}', type)
  }

  const headers = getHeaders()
  console.log(headers)
  if (this.loading !== undefined && loading) {
    this.loading = true
  }

  try {
    let res

    if (method === 'delete') {
      res = await axios[method](api, { headers })
    } else {
      res = await axios[method](api, data, { headers })
    }

    return getResponse(res)
  } catch (e) {
    console.log(e)
    return handleError(e)
  } finally {
    if (this.loading !== undefined && loading) {
      this.loading = false
    }
  }
}

export async function deleteRequest ({ api, type, id, loading = true }) {
  const result = await postRequest({ api, type, id, loading, method: 'delete' })
  return result
}

export async function patchRequest ({ api, id, type, data, loading = true }) {
  const result = await postRequest({ api, type, id, data, loading, method: 'patch' })
  return result
}

export async function putRequest ({ api, id, type, loading = true, data }) {
  const result = await postRequest({ api, type, id, data, loading, method: 'put' })
  return result
}

export function getMaxPage (count, limit) {
  return Math.ceil(count / limit)
}

export function getRoute ({ name, path, params, query }) {
  name = this.$route.name || name
  path = this.$route.path || path

  query = Object.assign({}, this.$route.query, query)
  params = Object.assign({}, this.$route.params, params)

  for (const key in query) {
    if (query[key] === undefined) {
      delete query[key]
    }
  }

  return { name, path, params, query }
}

export async function getOssToken (path) {
  const api = '/api/common/oss_token/'
  const headers = getHeaders()
  const params = { module: path }

  try {
    const res = await axios.get(api, { headers, params })
    return getResponse(res)
  } catch (e) {
    return handleError(e)
  } finally {
  }
}
